<?php

namespace App\Trip\Orders\BookOrders\Params;

use App\Trip\Enums\OrderBusiness;
use App\Trip\Enums\TripTypes;
use App\Trip\Orders\BookOrders\Params\AbstractOrderParam\AbstractSnapOrderParam;
use App\Trip\Orders\BookOrders\SnapUp\SnapUpData;
use Carbon\Carbon;
use Illuminate\Support\Facades\Validator;
use InvalidArgumentException;

class SnapOrderParam extends AbstractSnapOrderParam
{

    public array           $order_data;
    private SnapParam|null $snapParam = null;


    public function __construct(array $param, ?SnapParam $snapParam = null)
    {
        $this->order_data = $param;
        if ($snapParam) {
            $this->snapParam = $snapParam;
        }

        if (!isset($this->trip_id)) {
            $this->order_data['trip_id'] = generate_order_id(TripTypes::TRAIN, OrderBusiness::SNAP);
        }
    }

    public function getSelectSeat(): array
    {
        return ($this->seats ?? []) ?: [];
    }

    public function OrderService(): string
    {
        return 'piaochi';
    }

    public function isSnapUp(): bool
    {
        return true;
    }

    /**
     * 备选坐席 ["无座","一等座","硬卧"]
     * 将当前默认的坐席加入,减少计算
     *
     * @return array
     */

    public function getAlternativeSeats(): array
    {
        $curr_seat = $this->getOrder()['seat_type'];
        $seats     = ($this->alternative_seats ?? []) ?: [];
        $seats[]   = $curr_seat;
        return array_unique($seats);
    }

    public function getOrder(): array
    {
        $validator = Validator::make($this->order_data, []);
        if ($validator->fails()) {
            throw new InvalidArgumentException($validator->errors()->first());
        }

        return $this->order_data;
    }

    /**
     * 备选车次  含车次号 出发code,name,time 目的code,name,time
     *
     * @return array
     */

    public function getAlternativeTrains(): array
    {
        $train_param = $this->getTripParam();
        $trains      = ($this->alternative_trains ?? []) ?: [];
        // 获取当前默认车次并加入
        $trains[] = [
            "train_code"   => $train_param->getTripCode(),
            "arrive_time"  => $train_param->getArriveTime(),
            "start_time"   => $train_param->getStartTime(),
            "from_code"    => $train_param->getFromCode(),
            "to_code"      => $train_param->getToCode(),
            "from_name"    => $train_param->getFromName(),
            "to_name"      => $train_param->getToName(),
            "from_name_uy" => $train_param->getFromNameUy(),
            "to_name_uy"   => $train_param->getToNameUy(),
        ];
        return collect($trains)->unique(fn($train) => "{$train["train_code"]}_{$train["from_code"]}_{$train["to_code"]}")->toArray();
    }

    /**
     * 备选日期  ["2022-07-12","2022-07-13"]
     * 将当前默认的日期加入,减少计算
     *
     * @return array
     */
    public function getAlternativeTrainDates(): array
    {
        $curr_train_date = Carbon::parse($this->getOrder()['start_at'])->toDateString();
        $dates           = ($this->alternative_train_dates ?? []) ?: [];
        $dates[]         = $curr_train_date;
        return collect($dates)
            ->map(function ($date) {
                if (Carbon::parse($date)->greaterThanOrEqualTo(Carbon::today())) {
                    return $date;
                }
                return null;
            })->unique()->filter()->toArray();
    }

    /**
     * @inheritDoc
     */
    public function getStopTime(): int
    {
        return $this->getSnapParam()->getStopTime();
    }

    public function getSnapParam(): SnapParam
    {
        if ($this->snapParam instanceof SnapParam) {
            return $this->snapParam;
        }
        if ($this->order_data['snap_param'] instanceof SnapParam) {
            return $this->order_data['snap_param'];
        } else {
            return new SnapParam($this->order_data['snap_param']);
        }
    }

    public function getOutOrderSn(): string
    {
        return $this->getTripId();
    }

    public function getTripId(): string
    {
        return $this->trip_id;
    }

    public function getSnapData(): SnapUpData
    {
        return new SnapUpData($this->getOrder());
    }
}